﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Sora.HelpSystem.Package;
using Sora.HelpSystem.Package.Pages;
using System.Windows.Controls.Primitives;

namespace Sora.HelpSystem.UI.WPF
{
    /// <summary>
    /// Interaction logic for HelpContentSummary.xaml
    /// </summary>
    public partial class HelpContentSummary : UserControl
    {
        private HelpDocumentProvider DocumentProvider { get; set; }

        #region Dependency Properties

        public HelpDocument Document
        {
            get { return (HelpDocument)GetValue(DocumentProperty); }
            set { SetValue(DocumentProperty, value); }
        }
        
        public static readonly DependencyProperty DocumentProperty =
            DependencyProperty.Register("Document", typeof(HelpDocument), typeof(HelpContentSummary), new PropertyMetadata(DocumentPropertyChanged));

        public Uri SelectedUri
        {
            get { return (Uri)GetValue(SelectedUriProperty.DependencyProperty); }
            private set { SetValue(SelectedUriProperty, value); }
        }

        public static readonly DependencyPropertyKey SelectedUriProperty =
            DependencyProperty.RegisterReadOnly("SelectedUri", typeof(Uri), typeof(HelpContentSummary), new PropertyMetadata(null, SelectedUriPropertyChanged));

        public HelpPage DocumentRoot
        {
            get { return (HelpPage)GetValue(DocumentRootProperty.DependencyProperty); }
            private set { SetValue(DocumentRootProperty, value); }
        }

        public static readonly DependencyPropertyKey DocumentRootProperty =
            DependencyProperty.RegisterReadOnly("DocumentRoot", typeof(HelpPage), typeof(HelpContentSummary), new PropertyMetadata(null));

        #endregion

        #region Dependecy Properties Changed Event Handlers

        private static void DocumentPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var summary = sender as HelpContentSummary;
            
            if (summary != null)
            {
                if (e.NewValue == null)
                {
                    summary.DocumentProvider = null;
                    summary.DocumentRoot = null;
                }
                else
                {
                    var doc = (HelpDocument)e.NewValue;

                    summary.DocumentProvider = new HelpDocumentProvider(doc);
                    summary.DocumentRoot = summary.DocumentProvider.ResolveUri(doc.DocumentBaseUri);
                }

                summary.helpSummary.DataContext = e.NewValue;

                summary.CoerceValue(SelectedUriProperty.DependencyProperty);
                summary.CoerceValue(DocumentRootProperty.DependencyProperty);
            }
        }

        public event EventHandler SelectedUriChanged;

        private static void SelectedUriPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var summary = sender as HelpContentSummary;

            if (summary != null)
            {
                if (summary.SelectedUriChanged != null)
                    summary.SelectedUriChanged(summary, EventArgs.Empty);
            }
        }

        #endregion

        public HelpContentSummary()
        {
            InitializeComponent();
        }

        private void helpSummary_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            var page = e.NewValue as HelpPage;

            SelectedUri = page != null ? page.Uri : null;
        }

        public void SelectItem(HelpPage page)
        {
            if (page != null)
            {
                var objPath = new List<HelpPage>();
                var current = page;

                while (current != null)
                {
                    objPath.Add(current);
                    current = current.Parent;
                }

                /* sélection dans l'ordre des parents (donc inverse à l'ajout) */
                var currentItems = helpSummary.Items;
                TreeViewItem lastItem = null;

                for (int i = objPath.Count - 1; i >= 0 && currentItems != null; i--)
                {
                    var tmp = lastItem;
                    lastItem = null;

                    foreach (HelpPage o_item in currentItems)
                    {
                        TreeViewItem item = null;

                        if (helpSummary.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)
                        {
                            /* chaque TreeViewItem contient le générateur de ses enfants
                             * (qui n'est donc pas le même à chaque niveau ...)
                             */
                            if (tmp == null)
                                item = (TreeViewItem)helpSummary.ItemContainerGenerator.ContainerFromItem(o_item);
                            else
                                item = (TreeViewItem)tmp.ItemContainerGenerator.ContainerFromItem(o_item);

                            if (item.DataContext == objPath[i])
                            {
                                item.IsExpanded = true;

                                /* Les items sont virtualisés, donc le générateur renverra null sauf si les
                                 * enfants ont déjà été affiché ou si on appelle pas UpdateLayout
                                 */
                                item.UpdateLayout();

                                lastItem = item;
                                break;
                            }
                        }
                        else
                            break;
                    }

                    if (lastItem != null)
                    {
                        currentItems = lastItem.Items;
                    }
                }

                if (lastItem != null)
                    lastItem.IsSelected = true;
            }
        }

        private void helpSummary_Selected(object sender, RoutedEventArgs e)
        {
            /* BUGFIX
             * cf http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/61a062ef-058f-43ea-ad18-3d08e6bd8765
             * */

            TreeViewItem tvi = e.OriginalSource as TreeViewItem;

            if (tvi != null && !tvi.IsFocused)
            {
                tvi.Focus();
            }
        }
    }
}
